package com.ordos.recruit.module.file.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ordos.recruit.module.file.service.FileService;
import com.ordos.recruit.module.user.entity.SysSsoUserDto;
import com.ordos.recruit.module.user.exception.UserLoginException;
import com.ordos.recruit.module.user.util.UserUtil;
import com.ordos.recruit.util.HttpUtils;
import com.wonders.commons.util.response.ApiResponse;
import lombok.RequiredArgsConstructor;
import okhttp3.RequestBody;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 *
 * </p>
 *
 * @author fw
 * @date 2022/4/19 18:48
 */
@RestController
@RequestMapping("apply")
@RequiredArgsConstructor
public class FileController {

    @Value("${userfiles.basedir}")
    private String uploadPath;//上传文件路径
    @Value("${userfiles.uploadFileUrl}")
    private String uploadFileUrl;//上传文件路径
    @Value("${userfiles.deleteFileUrl}")
    private String deleteFileUrl;//删除文件路径
    @Value("${userfiles.showFileUrl}")
    private String showFileUrl;//回显文件路径
    @Value("#{'${userfiles.contenttype:}'.split(',')}")
    private List<String> contenttype;
    @Value("#{'${userfiles.filetypes:}'.split(',')}")
    private List<String> filetypes;
    private final FileService fileService;
    private final Logger logger= LoggerFactory.getLogger(FileController.class);

    /**
     * 文件回显
     * @param id 文件code
     * @return ResultEntity
     */
    @GetMapping("getFile")
    public ApiResponse<String> showDocFile(String id) {
        if (StrUtil.isBlank(id)) {
            return ApiResponse.error("文件唯一标识不能为空!");
        }
        try {
            String url = uploadFileUrl+ "/rczpUploadFile/doc/findFile";
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("fileCode", id);
            OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
            MediaType mediaType = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式，
            RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(paramMap));
            Request request = new Request.Builder().url(url)
                    .addHeader("Content-Type","application/json")
                    .post(body).build();
            final Call call = client.newCall(request);
            Response responseOk = call.execute();
            String result = responseOk.body().string();
            logger.info("返回结果:" + result);
            JSONObject jso = JSONObject.parseObject(result);
            JSONArray data = (JSONArray) jso.get("data");
            String httpPath = "";
            if (data != null && data.size() > 0) {
                JSONObject cc = (JSONObject) data.get(0);
                httpPath = showFileUrl + "/files" + cc.get("httpPath").toString();
            }
            return ApiResponse.success(httpPath);
        } catch (Exception e) {
            e.printStackTrace();
            return ApiResponse.error("接口异常："+e.getMessage());
        }
    }

    /**
     * 文件上传
     * @param file  文件
     * @return ResultEntity
     * @throws IOException
     */
    @PostMapping("fileUpload")
    public ApiResponse<Object> uploadToDoc(@RequestParam(value="file",required=false) MultipartFile file) throws IOException {
        SysSsoUserDto userByRequest = UserUtil.getUserByRequest();
        if (userByRequest == null) {
            throw new UserLoginException("获取用户信息失败， 请检查当前Cookie状态.");
        }
        JSONObject json = new JSONObject();
        Response response =null;
                if (file == null || file.isEmpty() || file.getSize() == 0) {
                    return ApiResponse.error("您上传的文件是空的，请重新选择一个后再次上传!");
                }
                if(!contenttype.contains(file.getContentType())) {
                    return ApiResponse.error("不支持的文件格式!");
                }
                if(10485760 < file.getSize()) {
                    return ApiResponse.error("上传的图片文件不要超过10M!");
                }
                String originFileName = file.getOriginalFilename(); // 获取文件的原始文件名
                String fileType = originFileName.substring(originFileName.lastIndexOf(".") + 1);
                if(!filetypes.contains(fileType)) {
                    return ApiResponse.error("不支持的文件格式!");
                }
                String fileCode=UUID.randomUUID().toString().replace("-","");
                String filename = originFileName.substring(0,originFileName.lastIndexOf("."));

                /**
                 ** 文件名里不能含有特殊字符
                 */
                String regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？ ]";
                Pattern p = Pattern.compile(regEx);
                Matcher m = p.matcher(filename);
                if(m.find()) {
                    return ApiResponse.error("上传的文件名不能含有特殊字符");
                }
                String filePath = uploadPath + File.separator + originFileName;
                File uploadFile = new File(filePath);
        try {
                if (!uploadFile.getParentFile().exists()) { // 如果父目录不存在，创建父目录
                    uploadFile.getParentFile().mkdirs();
                }
                if (uploadFile.exists()) { // 如果已存在,删除旧文件
                    uploadFile.delete();
                }
                uploadFile.createNewFile();
                file.transferTo(uploadFile); // 将文件写入磁盘
                String url = uploadFileUrl + "/rczpUploadFile/doc/fileUpLoad";
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                builder.connectTimeout(1, TimeUnit.MINUTES);
                builder.readTimeout(1,TimeUnit.MINUTES);
                OkHttpClient okHttpClient = builder
                        .build();
                RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), uploadFile);

                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("doc", originFileName, fileBody)
                        .addFormDataPart("fileType", fileType)
                        .addFormDataPart("fileName", originFileName)
                        .addFormDataPart("fileCode", fileCode)
                        .build();
                Request request = new Request.Builder()
                        .url(url)
                        .post(requestBody)
                        .build();
                response = okHttpClient.newCall(request).execute();
                //String result = response.body().string();

                ApiResponse resultEn = this.showDocFile(fileCode);
                String httpPath="";
                if(resultEn.isSuccess()){
                    httpPath= resultEn.getData().toString();
                }
                json.put("httpPath", httpPath);
                json.put("fileCode", fileCode);
                deleteDir(uploadFile);
                //设置操作人
                fileService.updateFile(fileCode,userByRequest.getUserid());
                return ApiResponse.success(json);

        } catch (Exception e) {
            e.printStackTrace();
            if (uploadFile.exists()) { // 如果已存在,删除旧文件
                uploadFile.delete();
            }
            return ApiResponse.error("文件上传异常,请重新上传!"+e.getMessage());
        }finally {
            if(null !=response){
                response.close();
            }
        }
    }

    /**
     * 删除文件
     * @param fileCode 文件编码
     * @return ResultEntity
     * @throws IOException
     */
    @PostMapping("deletePic")
    public ApiResponse<String> deletePic(String fileCode) throws IOException {
        if(StrUtil.isEmpty(fileCode)){
            return ApiResponse.error("文件编码不可为空");
        }
        JSONObject json = new JSONObject();
        json.put("fileCode",fileCode);
        JSONObject jsonObject = HttpUtils.requestPost(deleteFileUrl, json.toJSONString());
        if(jsonObject.getString("code").equals("SUCCESS")){
            return ApiResponse.success();
        }
        return ApiResponse.error(jsonObject.getString("msg"));
    }
    private static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }
}
